package com.fjeld.client.gui.screens.node;

import com.fjeld.swingx.JTransparentPanel;
import com.fjeld.swingx.JRoundedButton;
import com.fjeld.middleware.jaxb.V1Node;
import com.fjeld.middleware.jaxb.V1ID;
import com.fjeld.client.gui.util.factories.LabelFactory;
import com.fjeld.client.gui.TradingFrontEnd;
import com.fjeld.client.util.cache.ClientCacheManager;
import com.explodingpixels.macwidgets.HudWindow;
import com.explodingpixels.macwidgets.HudWidgetFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.*;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: fjelds
 * Date: Mar 21, 2010
 * Time: 11:58:34 AM
 * <p/>
 * Displays the various information bits/bobs for a node, including environments.
 * <p/>
 * The encapsulated content node displays the name of the node and creates a
 * environment view for every V1ID reference. Can also create new environments.
 */
public class NodeView extends JTransparentPanel implements Observer, ActionListener
{
    private static final ClientCacheManager CCM = ClientCacheManager.getInstance();
    private V1Node contentNode;
    private JLabel label;
    private Box environmentBox;
    private JButton addEnvironmentButton;
    private JButton addActionButton;
    private Box buttonBox;
    private List<String> environmentOptions = new ArrayList<String>();
    private Map<String, V1Node> envNodeMap = new HashMap<String, V1Node>();

    public NodeView(V1Node contentNode)
    {
        //super(0, INFORBAR_BOTTOM_LINE, INFOBAR_BOTTOM_GRADIENT, INFORBAR_BOTTOM_LINE, INFOBAR_TOP_GRADIENT, INFOBAR_LIGHT_LINE);
        this.contentNode = contentNode;

        // Set up header
        label = LabelFactory.createHeaderLargeLabelNonPadded(contentNode.getName());
        this.add(label, BorderLayout.NORTH);

        JTransparentPanel buttonPanel = setupButtons();
        JPanel environmentListingPanel = new JTransparentPanel();
        environmentBox = Box.createHorizontalBox();
        environmentListingPanel.add(environmentBox, BorderLayout.NORTH);


        // Environment view + controllers setup
        JLabel envHeader = LabelFactory.createHeaderLabelNonPadded("Environments:");
        JTransparentPanel envContent = new JTransparentPanel();
        envContent.add(envHeader, BorderLayout.NORTH);
        envContent.add(environmentListingPanel, BorderLayout.WEST);
        envContent.add(buttonPanel, BorderLayout.SOUTH);

        this.add(envContent, BorderLayout.CENTER);
        updateEnvironmentsAvailable();

        contentNode.addObserver(this);
        setBorder(BorderFactory.createEmptyBorder(0,10,0,0));
    }

    private JTransparentPanel setupButtons()
    {
        // Button setup
        addEnvironmentButton = new JRoundedButton("+ Environment");
        addEnvironmentButton.addActionListener(this);

        addActionButton = new JRoundedButton("+ Action");
        addActionButton.addActionListener(this);

        buttonBox = Box.createHorizontalBox();
        buttonBox.add(addEnvironmentButton);
        buttonBox.add(Box.createHorizontalStrut(15));
        buttonBox.add(addActionButton);

        JTransparentPanel buttonPanel = new JTransparentPanel();
        buttonPanel.add(buttonBox, BorderLayout.WEST);
        return buttonPanel;
    }

    // Brute force simply because it's faster to develop. Most of the time envs wont be modified.
    // TODO: optimise somewhat
    private void updateEnvironmentsAvailable()
    {
        environmentBox.removeAll();
        environmentOptions.clear();
        envNodeMap.clear();

        for (V1ID nodeReference : contentNode.getV1ID())
        {
            EnvironmentView envView = new EnvironmentView(nodeReference);
            environmentBox.add(envView);
            V1Node environmentDescriptionNode = CCM.getNode(nodeReference.getNodeID());
            environmentOptions.add(environmentDescriptionNode.getName());
            envNodeMap.put(environmentDescriptionNode.getName(), environmentDescriptionNode);
        }

        revalidate();
        repaint();
    }

    public void update(Observable observable, Object o)
    {
        label.setText(contentNode.getName());
        updateEnvironmentsAvailable();
        revalidate();
        repaint();
    }

    public void actionPerformed(ActionEvent actionEvent)
    {
        if (actionEvent.getSource() == addEnvironmentButton)
        {
            addNewEnvironment();
        } else if (actionEvent.getSource() == addActionButton)
        {
            addNewAction();
        }
    }

    private void addNewAction()
    {
           new ActionEntryDialog("Enter the name of the action:",
                    "Add new action", environmentOptions);
    }

    private void addNewEnvironment()
    {
        new TextEntryDialog("Add new environment", "\nEnter the name of the environment:\n");
    }

    private class TextEntryDialog extends HudWindow implements ActionListener
    {
        private JTextField textField;

        public TextEntryDialog(String title, String text)
        {
            super(title);

            JButton ok = new JRoundedButton("OK");
            ok.addActionListener(this);
            JLabel label = LabelFactory.createHeaderLabel(text);
            textField = HudWidgetFactory.createHudTextField("");

            Box box = Box.createVerticalBox();
            box.add(Box.createVerticalStrut(5));
            box.add(label);
            box.add(Box.createVerticalStrut(10));
            box.add(textField);
            box.add(Box.createVerticalStrut(10));
            box.add(ok);
            box.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

            getContentPane().setLayout(new BorderLayout());
            getContentPane().add(box, BorderLayout.NORTH);

            getJDialog().setSize(300, 150);
            getJDialog().setLocationRelativeTo(TradingFrontEnd.frame);
            getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            getJDialog().setVisible(true);
        }

        public void actionPerformed(ActionEvent actionEvent)
        {
            String userEntry = textField.getText();

            if (userEntry != null && userEntry.length() > 0)
                CCM.addEnvironmentToNode(contentNode.getNodeID(), userEntry);

            getJDialog().setVisible(false);
        }
    }

    private class ActionEntryDialog extends HudWindow implements ActionListener
    {
        private JTextField textField;
        private JComboBox comboBox;

        public ActionEntryDialog(String title, String text, List<String> list)
        {
            super(title);

            String[] stringList = new String[list.size()];
            for (int i=0; i < list.size(); i++)
            {
                String string = list.get(i);
                stringList[i] = string;
            }

            JButton ok = new JRoundedButton("OK");
            ok.addActionListener(this);
            JLabel label = LabelFactory.createHeaderLabel(text);
            textField = HudWidgetFactory.createHudTextField("");

            comboBox = HudWidgetFactory.createHudComboBox(new DefaultComboBoxModel(stringList));

            Box box = Box.createVerticalBox();
            box.add(Box.createVerticalStrut(5));
            box.add(label);
            box.add(Box.createVerticalStrut(10));
            box.add(textField);
            box.add(Box.createVerticalStrut(10));
            box.add(comboBox);
            box.add(Box.createVerticalStrut(10));
            box.add(ok);
            box.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

            getContentPane().setLayout(new BorderLayout());
            getContentPane().add(box, BorderLayout.NORTH);

            getJDialog().setSize(300, 200);
            getJDialog().setLocationRelativeTo(TradingFrontEnd.frame);
            getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            getJDialog().setVisible(true);
        }

        public void actionPerformed(ActionEvent actionEvent)
        {
            String userEntry = textField.getText();

            if (userEntry != null && userEntry.length() > 0)
            {
                String environmentName = (String) comboBox.getSelectedItem();
                V1Node node = envNodeMap.get(environmentName);
                CCM.addActionToEnvironment(node.getNodeID(), userEntry);
            }

            getJDialog().setVisible(false);
        }
    }

}
